package com.gome.ss.common;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.Properties;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.gome.spiderkit.client.GlobalConfig;
import com.gome.ss.core.plugin.PluginGlobal;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import com.mongodb.ServerAddress;

public class AppConfiguer {
	private static Logger logger = null;
	
	public static final String FLOWCRAWL_MONGODB_HOST_KEY = "flowcrawlMongodbHost";
	public static final String FLOWCRAWL_MONGODB_PORT_KEY = "flowcrawlMongodbPort";
	public static final String FLOWCRAWL_USE_HBASE_TRANSIT_KEY = "flowcrawlUseHBaseTransit";
	public static final String FLOWCRAWL_DB_NAME = "flowcrawl";
	public static final String FLOWCRAWL_CONFIG_COLLECTION_NAME = "config";
	public static final String FLOWCRAWL_EXTRACT_COLLECTION_NAME = "extract";
	public static final String LOG_PATH = "logPath";
	public static final String LOG_LEVEL = "logLevel";
	public static final String PLUGIN_DIR = "pluginDir";
	
	public static final String SS_DB_NAME = "plugin-schedule";
	public static final String SS_TASK_COLLECTION_NAME = "tasks";
	
	public static final String NULL_JSON_OBJECT = "{}";
	public static final String NULL_JSON_ARRAY = "[]";
	
	private static final String path = getConfDir() + "default.properties";
	public static final String pluginTaskIDPrefix = "PTask-";
	public static Mongo flowCrawlConfigMongo = null;
	public static Mongo ssMongo = null;
	
	private static String pluginDir = null;
	public static boolean flowcrawlUseHbaseTransit = true;
	public static ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
	
	public static String getJSLibraryDir() {
		return System.getProperty("user.dir") + "/jslib/";
	}
	
	public static String getConfDir() {
		return System.getProperty("user.dir") + "/config/";
	}
	
	public static String getPluginDir() {
		if (pluginDir == null) {
			pluginDir = getStringByKey(PLUGIN_DIR);
			if (!pluginDir.endsWith("/")) {
				pluginDir += "/";
			}
		}
		
		return pluginDir;
	}
	
	public static String getValueByKey(String key) {
		Properties pps = new Properties();
		InputStream in;
		try {
			in = new BufferedInputStream (new FileInputStream(path));
			pps.load(in);
			String value = pps.getProperty(key);
			in.close();
			System.out.println(value);
			return value;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error(Utils.getTrace(e));
			return null;
		}
	}
	
	public static String getStringByKey(String key) {
		return getValueByKey(key);
	}
	
	public static int getIntByKey(String key) {
		Properties pps = new Properties();
		InputStream in;
		try {
			in = new BufferedInputStream (new FileInputStream(path));
			pps.load(in);
			String value = pps.getProperty(key);
			in.close();
			return Integer.parseInt(value, 10);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error(Utils.getTrace(e));
			return 0;
		}
	}
	
	public static int getThreadLimit() {
		return getIntByKey("threadLimit");
	}
	
	public static void initLog4j() {
		 String logPath = AppConfiguer.getStringByKey(LOG_PATH);
		 String logLevel = AppConfiguer.getStringByKey(LOG_LEVEL);
		 
		 Properties props = new Properties();
		 props.setProperty("log4j.rootLogger", logLevel + ", A");
		 props.setProperty("log4j.appender.A", "org.apache.log4j.DailyRollingFileAppender");
		 props.setProperty("log4j.appender.A.File", logPath);
		 props.setProperty("log4j.appender.A.DatePattern", "'.'yyyy-MM-dd");
		 props.setProperty("log4j.appender.A.layout", "org.apache.log4j.PatternLayout");
		 props.setProperty("log4j.appender.A.layout.ConversionPattern", "%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n");
		 
		 PropertyConfigurator.configure(props);//装入log4j配置信息
		 
		 logger = Logger.getLogger(AppConfiguer.class);
	}
	
	public static void initFlowCrawlSpider() {
		flowcrawlUseHbaseTransit = AppConfiguer.getStringByKey(FLOWCRAWL_USE_HBASE_TRANSIT_KEY).equals("1") ? true : false;
		if (flowCrawlConfigMongo == null) {
			try {
				MongoOptions options = new MongoOptions();
				options.connectionsPerHost = 100;
				options.autoConnectRetry = true;
				options.threadsAllowedToBlockForConnectionMultiplier=5;
				options.slaveOk = true;
				ServerAddress serverAddress=new ServerAddress(getStringByKey(FLOWCRAWL_MONGODB_HOST_KEY), getIntByKey(FLOWCRAWL_MONGODB_PORT_KEY));
				flowCrawlConfigMongo = new Mongo(serverAddress, options);
			} catch (UnknownHostException e) {
				logger.error(Utils.getTrace(e));
				return;
			}
		}
	}

	public static void initSSDB() {
		if (ssMongo == null) {
			try {
				MongoOptions options = new MongoOptions();
				options.connectionsPerHost = 10;
				options.autoConnectRetry = true;
				options.threadsAllowedToBlockForConnectionMultiplier=5;
				options.slaveOk = true;
				ServerAddress serverAddress=new ServerAddress(getStringByKey(FLOWCRAWL_MONGODB_HOST_KEY), getIntByKey(FLOWCRAWL_MONGODB_PORT_KEY));
				ssMongo = new Mongo(serverAddress, options);
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				logger.error(Utils.getTrace(e));
				return;
			}
		}
		PluginGlobal.redisHost = getStringByKey("redisHost");
		PluginGlobal.redisPort = getIntByKey("redisPort");
	}
	
	public static void initSpiderkitClient() throws IOException, InterruptedException {
		String zkhost = getStringByKey("zookeeperHost");
		GlobalConfig config = GlobalConfig.getInstance();
		config.connect(zkhost);
	}
	
	public static ScriptEngine constructJavaScriptEngine() {
		ScriptEngine jsEngine = scriptEngineManager.getEngineByName("js");
		
		File dir = new File(AppConfiguer.getJSLibraryDir());
		if (!dir.exists())
			return null;
		File[] files = dir.listFiles();
		for ( File jslibFile : files ) {
			if ( jslibFile.isFile() ) {
				String jslibFileName = jslibFile.getName();
				if ( ! jslibFileName.endsWith(".js") )
					continue;
				try {
					jsEngine.eval(new FileReader(new File(AppConfiguer.getJSLibraryDir() + jslibFileName)));
				} catch (Exception e) {
					logger.error(Utils.getTrace(e));
					return null;
				}
			}
		}
		
		return jsEngine;
	}
}
